#-*- coding: utf-8 -*-
from cpu import cpuTime

def lecture(nom):
	fichier = open(nom)
	res = '' 
	for ligne in fichier:
		res += ligne
	return res	

def ecriture(nom, texte):
	fichier = file(nom, 'w') #en écriture
	fichier.write(texte)
	fichier.close()

def nettoyage_rplAcc(texte):
	"""
	Nettoie un texte.
	Entrée : Une chaine de caractère texte.
	FIXME
	Sortie : Une chaine de caractères correspondant au texte texte nettoyé. Pour nettoyer un
	texte, il suffit de mettre toutes les lettres en minuscule et supprimer les espaces, les caractères
	de retour à la ligne et les caractères spéciaux (é,ô,...).
	"""
	texte = texte.lower() #tout en minuscules
	#on élimine la ponctuation et d'autres trucs
	todel = ':;.,!-"\'\n\t ';
	for x in todel:
		texte = texte.replace(x, '')
	#après transformation en Unicode, on vire les accents
	texte = unicode(texte, 'utf-8')
	acc = zip(	u'éêèëíîìïàâôöùüç', 
				u'eeeeiiiiaaoouuc') #liste de couples
	for c in acc:
		texte = texte.replace(c[0], c[1])
	#on remballe le résultat
	return texte

def nettoyage(texte, enc='utf-8'):
	"""Nettoie un texte des espaces/tabs/accents en le mettant en minuscules."""
	texte = unicode(texte.lower(), enc)
	todel = u'éêèëíîìïàâôöùüç:;.,!-"\'\n\t '
	for c in todel:
		texte = texte.replace(c, '')
	return texte

def chiffrement_decalage_ord(texte, u):
	"""
	Chiffre un texte en utilisant la méthode de chiffrement par décalage.
	Méthode rapide utilisant le code ASCII de chaque caractère.
	"""
	nv = ''
	for lettre in texte:
		idx = ord(lettre) + u
		if idx<97:
			idx = 122 - (97-idx) + 1
		elif idx > 122:
			idx = 97 + (idx - 122) - 1
		nv += chr(idx)
	return nv

def chiffrement_decalage(texte, u):
	"""
	Chiffre un texte en utilisant la méthode de chiffrement par décalage.
	Méthode lente utilisant un dictionnaire...
	"""
	lettre_rang = {} #associe à chaque lettre son rang
	for i,t in enumerate('abcdefghijklmnopqrstuvwxyz'):
		lettre_rang[t] = i
	rang_lettre = {} #associe à chaque rang une lettre
	#version "light" car c'est toujours 1 clé / 1 valeur
	for k in lettre_rang:
		rang_lettre[lettre_rang[k]] = k
	nv = '' #résultat
	for lettre in texte:
		if lettre in lettre_rang.keys():
			pos = (lettre_rang[lettre] + u)
			if pos < 0:
				pos += 26
			elif pos > 25:
				pos -= 26
			nv += rang_lettre[pos]
		else:
			nv += lettre
	return nv

def dechiffrement_decalage(texte, u):
	return chiffrement_decalage(texte, -u)

def chiffrement_substitution(texte, dico):
	nv = ''
	for lettre in texte:
		if lettre in dico:
			lettre = dico[lettre]
		nv += lettre
	return nv

def dechiffrement_substitution(texte, dico):
	dico_inv = {}
	for k in dico:
		dico_inv[dico[k]] = k
	return chiffrement_substitution(texte, dico_inv)

dico = { 'a' : 'd', 'b' : 'c', 'c' : 'q', 'd' : 'r', 'e' : 'k', 'f' : 'n',
'g' : 'g', 'h' : 'v', 'i' : 'u', 'j' : 't', 'k' : 'x', 'l' : 'o',
'm' : 'i', 'n' : 'l', 'o' : 'a', 'p' : 'j', 'q' : 'y', 'r' : 'b',
's' : 's', 't' : 'z', 'u' : 'm', 'v' : 'p', 'w' : 'h', 'x' : 'w',
'y' : 'f', 'z' : 'e'}

"""
* "Travailler dur n'a jamais tué personne, mais pourquoi prendre le risque ?"
* C'est pour [censuré], ça...
* Mais le truc c'est qu'il ne le verra JAMAIS !
* C'est pas faux...
"""

def histogram(s):
	d={}
	for c in s:
		if c not in d:
			d[c] = 1
		else:
			d[c] += 1
	return d

def decouvre_clef(text, i):
	#on ne prend que les i premières lettres les plus fréquentes
	#en français (en général, pas dans le texte donné)
	freq = "eitnsaorlumcdpfqgvhbzyxkjw"[:i] #énoncé
	freq = "eaistnrulodmpcvqgbfjhzxykw"[:i] #fréq FR
	#on analyse le texte donné
	anz = histogram(text)
	#on retourne le dico
	anz_inv = {}
	for k in anz:
		if anz[k] in anz_inv:
			anz_inv[anz[k]].append(k)
		else:
			anz_inv[anz[k]] = [k]
	#on le transforme en tuples
	anz_inv = anz_inv.items()
	#on le trie dans l'ordre INVERSE
	anz_inv = sorted(anz_inv)
	anz_inv.reverse()
	#on remballe la réponse
	return zip([x[1] for x in anz_inv[:i]], freq)

def decouvre_texte(text, possb):
	#FIXME on devrait s'il y a plusieurs possibilités 
	#tester toutes les combis.
	k = dict([(x[0][0], x[1]) for x in possb])
	return chiffrement_substitution(text, k)


"""
victime = lecture('analyse.txt')
victime = nettoyage_rplAcc(victime)
possb = decouvre_clef(victime, 20)
print decouvre_texte(victime, possb)
"""

texte = nettoyage_rplAcc(lecture('iliade.txt'))
print texte
#ecriture('essai.txt', texte)
possb = decouvre_clef(texte, 26)
print possb
print texte
print decouvre_texte(texte, possb)
#print histo

if __name__ == '__main__':
	"""
	a = cpuTime('chiffrement_decalage', 'tp9', "'jpjvmzewtomanydjcbsi', 15")*1000
	b = cpuTime('chiffrement_decalage_ord', 'tp9', "'jpjvmzewtomanydjcbsi', 15")*1000
	print 'dico : %6.4f msec' % a
	print 'ord  : %6.4f msec' % b
	print 'rapport d/o : %4.2f' % (a/b)
	"""
